﻿
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;

namespace TrafficArchives.Common
{
    /// <summary>
    /// 查询项
    /// </summary>
    [DataContract]
    public class Condition
    {
        #region 构造函数

        /// <summary>
        /// 查询项
        /// </summary>
        public Condition()
        {
            IsGroupCondition = false;
            SubConditions = new List<Condition>();
        }

        /// <summary>
        /// 查询项
        /// </summary>
        /// <param name="isGroupCondition">是否组合查询条件</param>
        public Condition(bool isGroupCondition)
        {
            IsGroupCondition = isGroupCondition;
            SubConditions = new List<Condition>();
        }

        /// <summary>
        /// 查询项
        /// </summary>
        /// <param name="relation"></param>
        /// <param name="fieldName"></param>
        /// <param name="op"></param>
        /// <param name="values"></param>
        public Condition(ConditionRelation relation, string fieldName, ConditionOperator op, params object[] values)
        {
            IsGroupCondition = false;
            SubConditions = new List<Condition>();

            Relation = relation;
            FieldName = fieldName;
            Operator = op;
            Values = values;
        }

        #endregion 构造函数

        #region 属性

        /// <summary>
        /// 是否组合查询条件
        /// </summary>
        [DataMember]
        public bool IsGroupCondition
        {
            get;
            set;
        }

        /// <summary>
        /// 查询值集合
        /// </summary>
        [DataMember]
        public object[] Values
        {
            get;
            set;
        }

        /// <summary>
        /// 查询字段名称
        /// </summary>
        [DataMember]
        public string FieldName
        {
            get;
            set;
        }

        /// <summary>
        /// 查询条件操作符
        /// </summary>
        [DataMember]
        public ConditionOperator Operator
        {
            get;
            set;
        }

        /// <summary>
        /// 查询条件组合关系
        /// </summary>
        [DataMember]
        public ConditionRelation Relation
        {
            get;
            set;
        }

        /// <summary>
        /// 子查询条件集合
        /// </summary>
        [DataMember]
        public List<Condition> SubConditions
        {
            get;
            set;
        }

        #endregion 属性

        #region 函数

        /// <summary>
        /// 添加子查询条件
        /// </summary>
        /// <param name="item"></param>
        public void AddSubConditions(Condition item)
        {
            if (!IsGroupCondition)
                throw new InvalidOperationException("非组合查询条件不能添加子查询条件!");

            SubConditions.Add(item);
        }

        /// <summary>
        /// 添加多个子查询条件
        /// </summary>
        /// <param name="items"></param>
        public void AddSubConditions(IEnumerable<Condition> items)
        {
            if (!IsGroupCondition)
                throw new InvalidOperationException("非组合查询条件不能添加子查询条件!");

            SubConditions.AddRange(items);
        }

        #endregion 函数

        #region 方法

        /// <summary>
        /// 获取操作符
        /// </summary>
        /// <returns></returns>
        public string GetOperator()
        {
            switch (Operator)
            {
                case ConditionOperator.Like:
                    return "like";
                case ConditionOperator.In:
                    return "in";
                case ConditionOperator.NotIn:
                    return "not in";
                case ConditionOperator.Equal:
                    return "=";
                case ConditionOperator.Greater:
                    return ">";
                case ConditionOperator.GreaterAndEqual:
                    return ">=";
                case ConditionOperator.Less:
                    return "<";
                case ConditionOperator.LessAndEqual:
                    return "<=";
                case ConditionOperator.NotEqual:
                    return "!=";
                case ConditionOperator.ChildIn:
                    return "in";
                default:
                    throw new NotImplementedException();
            }
        }

        /// <summary>
        /// 获取查询值
        /// </summary>
        /// <returns></returns>
        public object GetValues()
        {
            if (Operator == ConditionOperator.Like)
            {
                if (Values == null || Values.Length <= 0) throw new ArgumentNullException();
                return string.Format("'%{0}%'", Values[0]);
            }

            if (Operator == ConditionOperator.In || Operator == ConditionOperator.NotIn)
            {
                if (Values == null || Values.Length <= 0) throw new ArgumentNullException();

                var sb = new StringBuilder();
                sb.Append("(");
                var length = Values.Length;
                for (var i = 0; i < length; i++)
                {
                    sb.Append(i == length - 1
                                  ? string.Format("'{0}'", Values[i])
                                  : string.Format("'{0}',", Values[i]));
                }
                sb.Append(")");
                return sb.ToString();
            }

            if (Operator == ConditionOperator.Equal ||
                Operator == ConditionOperator.Greater ||
                Operator == ConditionOperator.GreaterAndEqual ||
                Operator == ConditionOperator.Less ||
                Operator == ConditionOperator.LessAndEqual ||
                Operator == ConditionOperator.NotEqual)
            {
                if (Values == null || Values.Length <= 0) return null;

                return GetValueString(Values[0]);
            }

            // 子查询
            if (Operator == ConditionOperator.ChildIn)
            {
                if (Values == null || Values.Length <= 0)
                    return null;
                var sb = new StringBuilder();
                sb.Append("(");
                sb.Append(Values[0].ToString());
                sb.Append(")");
                return sb.ToString();
            }
            throw new InvalidOperationException();
        }

        /// <summary>
        /// 将查询条件的值转换为值字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetValueString(object value)
        {
            if (value is decimal)
            {
                return value.ToString();
            }
            if (value is DateTime)
            {
                // TODO: 目前只针对Oracle数据库做了实现
                return string.Format(" to_date('{0}','yyyy-mm-dd') ", ((DateTime)value).ToString("yyyy-MM-dd"));
            }
            if (value is double)
            {
                return value.ToString();
            }
            if (value is int)
            {
                return value.ToString();
            }
            if (value is bool)
            {
                return Convert.ToBoolean(value) ? "1" : "0";
            }
            if (value is long)
            {
                return value.ToString();
            }
            return "'" + value + "'";
        }

        #endregion 方法
    }
}